<?php
declare(strict_types=1);

namespace App\Middleware;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\Utils\Context;
use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Model\PssModel\Business;
use App\Model\PssModel\BusinessUser;

class RequestShopApiMiddleware implements MiddlewareInterface
{
    //访问频率限制key
    const VISIT_FREQUENCY_KEY   = 'mbyc_visit_frequency_key_';
    const VISIT_LIMIT           = 200;
    const VISTI_EXPIRE          = 60;
    protected $except = [
        '/shop/User/getVerifyImage',//图形验证码
        '/shop/User/UserLogin',//用户登录
        '/shop/User/sendSmsCode',//发送短信
        '/shop/User/verifyUser',//发送短信验证接口
        '/shop/User/userRegisterSave',//注册
        '/shop/User/reSetPassword',//找回密码
        '/shop/index/getBannerList',
        '/shop/index/getAdvertiseList',
        '/shop/index/getAdvertiseDetail',
        '/shop/index/getRecommandBrandList',
        '/shop/index/getAllShowTopicsList',
        '/shop/index/getSeckillList',
        '/shop/index/getSeckillGoodsList',
        '/shop/index/getGoodsGroupPageList',
        '/shop/index/getBrandList',
        '/shop/index/getClassList',
        '/shop/index/getGoodsDetail',
        '/shop/index/getGoodsList',
        '/shop/index/getSearchClassAndBrands',
        '/shop/Realtimedata/receive',
        '/shop/Realtimedata/receivedata',
        '/shop/index/getShopHomeGroupConfig',
        '/shop/index/getShopHomeGroupConfigDetail'
    ];
    
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var RequestInterface
     */
    protected $request;

    /**
     * @var HttpResponse
     */
    protected $response;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
    }

    //中间介质处理
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $param = $this->request->all();
        $token = $this->request->header('token');
        $token = $token ? $token : ($param['token']??'');
        $server_param = $request->getServerParams();
        $path_info = $server_param['path_info']??'';
        $server_param = [
            'ip'        => getIp(),
            'token'     => $token,
        ];
        $res = $this->_checkIsLogin($server_param);
        if( $res['code'] != Normal::SUC && !in_array($path_info,$this->except) ) {
            return $this->response->json($res);
        }
        
        //加入支付方式全局（登录之后需要payway）
        $param['pay_way'] = $this->request->header('payway');
        if( !empty($res['data']) && empty($param['pay_way']) && !in_array($path_info,$this->except) ) {
            return $this->response->json(Normal::returnCode(Normal::FAIL,"未传入支付方式"));
        }
        
        $body = array_merge([
            'binfo' => isset($res['data']) ? $res['data'] : [] ,
            'body'  => $param
        ]);
        $request = $request->withAttribute('param',$body);
        Context::set(RequestInterface::class, $request);
        return $handler->handle($request);
    }
    
    /**
     * 检查登录状态
     */
    protected function _checkIsLogin($server_param)
    {
        //检查访问频率
        $getIp = $server_param['ip'];
        $redis = BaseService::instance()->getRedisObj();
        /* if( !BaseService::instance()->visitFrequency(self::VISIT_FREQUENCY_KEY.$getIp,self::VISTI_EXPIRE,self::VISIT_LIMIT) ) {
            return Normal::returnCode(Normal::FAIL,"当前IP【{$getIp}】访问过于频繁，请稍后再试");
        } */
    
        $token = $server_param['token'];
        if( empty($token) ) {
            return Normal::returnCode(Normal::FAIL,"except param token");
        }
        
        $this->token = $token;
        $key    = BusinessUser::instance()->loginToken;
        $redis->select(BusinessUser::instance()->rdb);
        $cache  = $redis->get($key.$token);
        if( empty($cache) ) {
            return Normal::returnCode(Normal::NO_LOGIN,"登录失效");
        }
        
        $userInfo = explode('_', $cache);
        $expire   = $userInfo[3];
        $bid      = $userInfo[0];
        $binfo = Business::instance()->getUserInfoByBid($bid);
        return Normal::returnCode(Normal::SUC,"获取成功",$binfo);
    }
}